package com.kjc.demo.rcservice.app;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.TypeReference;
import com.kjc.demo.rcservice.bean.AppFileStoreBean;
import com.kjc.demo.rcservice.bean.AppInfoFileBean;
import com.kjc.demo.rcservice.configuration.Config;
import com.kjc.demo.rcservice.dto.AppInfoFileDTO;
import com.kjc.demo.rcservice.dto.req.AppInfoFileReqDTO;
import com.kjc.demo.rcservice.dto.res.AppInfoFileResDTO;
import com.kjc.demo.rcservice.service.AppFileStoreService;
import com.kjc.demo.rcservice.service.AppInfoFileService;
import com.kjc.demo.rcservice.util.Md5Util;
import com.sdhs.paas.sdk.base.common.BasePage;
import com.sdhs.paas.sdk.base.common.entity.PaginationEntity;
import com.sdhs.paas.sdk.base.dto.PageInfoDTO;
import com.sdhs.paas.sdk.base.utils.EntityDtoConvertUtil;
import com.sdhs.paas.sdk.core.PaasBaseException;
import com.sdhs.paas.sdk.core.PaasBaseRequest;
import com.sdhs.paas.sdk.core.PaasBaseResponse;
import com.sdhs.paas.sdk.core.RefreshableRestController;
import com.sdhs.paas.sdk.core.logger.Logger;
import com.sdhs.paas.sdk.core.logger.LoggerFactory;

/**
 * @author AppInfoFile
 * @version 1.0
 * @Title:  代码生成接口，用于接受前端传输过来的数据
 * @author kangjichang
 * @date 2018-09-21
 */
 
@RefreshableRestController
@RequestMapping(value = "/appInfoFile")
public class AppInfoFileController {
	
	private static Logger LOGGER  = LoggerFactory.getLogger(AppInfoFileController.class); 
	
	@Autowired
	private Config config;
	
    @Autowired
    private AppInfoFileService appInfoFileService;
    
    @Autowired
    private AppFileStoreService appFileStoreService;
    
    /**
     * 分页查询接口
     * */
    @PostMapping("/getAppInfoFilePageList")
	public PaasBaseResponse<AppInfoFileResDTO> getAppInfoFilePageList(@RequestBody PaasBaseRequest<AppInfoFileReqDTO> appInfoFileReqDTO) {
    	AppInfoFileDTO appInfoFileDTO = appInfoFileReqDTO.getBody().getAppInfoFileDTO();
    	PageInfoDTO pageInfoDTO = appInfoFileReqDTO.getBody().getPageInfo();
    	
		BasePage pageRequest = new BasePage();
		pageRequest.setPage(pageInfoDTO.getPage());
		pageRequest.setCount(pageInfoDTO.getPageSize());
    	
		AppInfoFileBean appInfoFileBean = EntityDtoConvertUtil.convertToEntity(appInfoFileDTO, AppInfoFileBean.class);
//    	Page<AppInfoFileBean> page = appInfoFileService.getPageAppInfoFileList(pageRequest, appInfoFileBean);
		PaginationEntity<AppInfoFileBean> page = appInfoFileService.getPageAppInfoFileListNew(pageRequest, appInfoFileBean);
    	PageInfoDTO resPageInfoDTO = new PageInfoDTO();
    	AppInfoFileResDTO appInfoFileResDTO = new AppInfoFileResDTO();
//    	resPageInfoDTO.setPage(page.getCurPage());
//		resPageInfoDTO.setPageSize(page.getPageSize());
//		resPageInfoDTO.setPageCount(page.getPageCount());
//		resPageInfoDTO.setRowCount(page.getTotalCount());
		resPageInfoDTO.setRowCount(page.getTotal());
		appInfoFileResDTO.setPageInfo(resPageInfoDTO);
//		List<AppInfoFileBean> appInfoFileBeanList = page.getResult();
		List<AppInfoFileBean> appInfoFileBeanList = page.getRows();
		List<AppInfoFileDTO> dtoList = new ArrayList<AppInfoFileDTO>();
		dtoList = EntityDtoConvertUtil.convertToDTOList(appInfoFileBeanList, new TypeReference<List<AppInfoFileDTO>>() {
		});
		appInfoFileResDTO.setAppInfoFileDTOList(dtoList);
    	return new PaasBaseResponse<>(appInfoFileResDTO);
	}
	
	/**
	 * 保存接口
	 * */
	@PostMapping("/saveAppInfoFile")
	public PaasBaseResponse<AppInfoFileResDTO> saveAppInfoFile(@RequestBody PaasBaseRequest<AppInfoFileReqDTO> appInfoFileReqDTO) {
		AppInfoFileDTO appInfoFileDTO = appInfoFileReqDTO.getBody().getAppInfoFileDTO();
		AppInfoFileBean appInfoFileBean = EntityDtoConvertUtil.convertToEntity(appInfoFileDTO, AppInfoFileBean.class);
		String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
		appInfoFileBean.setId(uuid);
		appInfoFileBean.setIsDeleted(0);
		appInfoFileBean.setType(1);
		Boolean flag = appInfoFileService.saveAppInfoFile(appInfoFileBean);
		appInfoFileDTO.setId(uuid);
		AppInfoFileResDTO appInfoFileResDTO = new AppInfoFileResDTO();
		appInfoFileResDTO.setAppInfoFileDTO(appInfoFileDTO);
		return new PaasBaseResponse<>(appInfoFileResDTO);
	}
	
	/**
	 * 修改接口
	 * */
	@PostMapping("/updateAppInfoFile")
	public PaasBaseResponse<AppInfoFileResDTO> updateAppInfoFile(@RequestBody PaasBaseRequest<AppInfoFileReqDTO> appInfoFileReqDTO) {
		AppInfoFileDTO appInfoFileDTO = appInfoFileReqDTO.getBody().getAppInfoFileDTO();
		AppInfoFileBean appInfoFileBean = EntityDtoConvertUtil.convertToEntity(appInfoFileDTO, AppInfoFileBean.class);
		Boolean flag = appInfoFileService.updateAppInfoFile(appInfoFileBean);
		AppInfoFileResDTO appInfoFileResDTO = new AppInfoFileResDTO();
		appInfoFileResDTO.setAppInfoFileDTO(appInfoFileDTO);
		return new PaasBaseResponse<>(appInfoFileResDTO);
	}
	
	/**
	 * 获取详情接口
	 * */
	@PostMapping("/getAppInfoFileDetail")
	public PaasBaseResponse<AppInfoFileResDTO> getAppInfoFileDetail(@RequestBody PaasBaseRequest<AppInfoFileReqDTO> appInfoFileReqDTO) {
		AppInfoFileDTO appInfoFileDTO = appInfoFileReqDTO.getBody().getAppInfoFileDTO();
		AppInfoFileBean appInfoFileBean = EntityDtoConvertUtil.convertToEntity(appInfoFileDTO, AppInfoFileBean.class);
		appInfoFileBean = appInfoFileService.getAppInfoFileDetail(appInfoFileBean.getId());
		appInfoFileDTO = EntityDtoConvertUtil.convertToDTO(appInfoFileBean, AppInfoFileDTO.class);
		AppInfoFileResDTO appInfoFileResDTO = new AppInfoFileResDTO();
		appInfoFileResDTO.setAppInfoFileDTO(appInfoFileDTO);
		return new PaasBaseResponse<>(appInfoFileResDTO);
	}
	
	/**
	 * 删除接口
	 * */
	@PostMapping("/deleteAppInfoFile")
	public PaasBaseResponse<AppInfoFileResDTO> deleteAppInfoFile(@RequestBody PaasBaseRequest<AppInfoFileReqDTO> appInfoFileReqDTO) {
		AppInfoFileDTO appInfoFileDTO = appInfoFileReqDTO.getBody().getAppInfoFileDTO();
		AppInfoFileBean appInfoFileBean = EntityDtoConvertUtil.convertToEntity(appInfoFileDTO, AppInfoFileBean.class);
		Boolean flag = appInfoFileService.deleteAppInfoFile(appInfoFileBean);
		AppInfoFileResDTO appInfoFileResDTO = new AppInfoFileResDTO();
		return new PaasBaseResponse<>(appInfoFileResDTO);
	}
	
	/**
	 * 终端日志文件上传接口
	 * @throws IOException 
	 * */
	@PostMapping("/fileUpload")
	public PaasBaseResponse<AppInfoFileResDTO> logUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
		 if (file.isEmpty())
	        {
			 throw new PaasBaseException("000001", "未发现导出文件");
	        }
	        // 创建父文件夹
//	      String dirPath = "F:/upload" ;
	        String dirPath = config.fileStorePath ;
	        String md5Hashcode = Md5Util.getFileStreamMD5((FileInputStream)file.getInputStream(),file.getSize());
	        // 生成目标文件路径
	        //真实的文件名存储到数据库中
	        String fileName = file.getOriginalFilename();
	        //apk版本号
	        String fileVersion = "";
	        //文件后缀名
	        String suffixName = fileName.substring(fileName.lastIndexOf("."));
	        //生成新的文件名，存储时使用，避免重复上传相同名称的文件，相互覆盖
	        String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
	        String dataPath = this.datePath();
	        String filePath = dirPath + dataPath + uuid+suffixName;
//	        String filePath = dirPath + File.separator + uuid+suffixName;
	        File destFile = new File(filePath);
	        // 检测是否存在目录
	        if (!destFile.getParentFile().exists()) {
	        	destFile.getParentFile().mkdirs();// 新建文件夹
	        }
	        try
	        {
	            // 记录上传记录
	            // 保存文件
	            file.transferTo(destFile);
//	            fileVersion = ApkSignUtil.getApkVersion(destFile);
	            AppFileStoreBean  appFileStoreBean = new AppFileStoreBean();
	            appFileStoreBean.setId(uuid);
	            appFileStoreBean.setIsDeleted(0);
	            appFileStoreBean.setName(fileName);
	            appFileStoreBean.setMimeType(suffixName);
	            appFileStoreBean.setSize(Long.valueOf(file.getSize()).intValue());
	            appFileStoreBean.setFilePath(dataPath);
	            appFileStoreBean.setHashCode(md5Hashcode);
	            Boolean flag = appFileStoreService.saveAppFileStore(appFileStoreBean);
	            if(!flag){
	            	throw new PaasBaseException("000001","文件信息存储失败！");
	            }
	            // 读取文件数据保存到数据库
	            //返回前端数据
	            AppInfoFileResDTO appInfoFileResDTO = new AppInfoFileResDTO();
	            AppInfoFileDTO appInfoFileDTO = new AppInfoFileDTO();
	            appInfoFileDTO.setId(uuid);
	            appInfoFileDTO.setFileName(fileName);
	            appInfoFileDTO.setFileVersion(fileVersion);
	            appInfoFileResDTO.setAppInfoFileDTO(appInfoFileDTO);
	            return new PaasBaseResponse<>(appInfoFileResDTO);
	        }
	        catch (Exception e)
	        {
	        	e.printStackTrace();
	        	throw new PaasBaseException("000001", "上传文件失败");
	        }
	}

	@GetMapping(value = "/fileDownload")
    public void fileDownload(HttpServletRequest request, HttpServletResponse res) {
	  String id = request.getParameter("id");
	  //根据Id查询文件存储信息
	  AppFileStoreBean appFileStoreBean = appFileStoreService.getAppFileStoreDetail(id);
      String fileName = appFileStoreBean.getName();
      res.setHeader("content-type", "application/octet-stream");
      res.setContentType("application/octet-stream");
      res.setHeader("Content-Disposition", "attachment;filename=\"" + fileName+"\"");
      String dirPath = config.fileStorePath;
      String filePath = dirPath + appFileStoreBean.getFilePath() + id + appFileStoreBean.getMimeType();
      byte[] buff = new byte[1024];
      BufferedInputStream bis = null;
      OutputStream os = null;
      try {
        os = res.getOutputStream();
        bis = new BufferedInputStream(new FileInputStream(new File(filePath)));
        int i = bis.read(buff);
        while (i != -1) {
          os.write(buff, 0, i);
          i = bis.read(buff);
        }
        
      } catch (IOException e) {
        e.printStackTrace();
      } finally {
        if (os != null) {
          try {
        	  os.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
        if (bis != null) {
            try {
            	bis.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
      }
    }

	/**
	 * 文件上传接口
	 * @throws IOException 
	 * */
	@PostMapping("/logUpload")
	public PaasBaseResponse<AppInfoFileResDTO> fileUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
		 if (file.isEmpty())
	        {
			 LOGGER.info("终端上传的日志文件为空！！！！！！！");
			 throw new PaasBaseException("000001", "未发现导出文件");
	        }
		 	/**
		    * deviceId：终端序列号
		    * token： 认证的token
		    * */
		   String deviceId = request.getParameter("device_id");
		   String token = request.getHeader("token");
		   LOGGER.info("终端上传的设备ID："+deviceId+"token："+token);
	        // 创建父文件夹
//	      String dirPath = "F:/upload" ;
	        String dirPath = config.fileStorePath ;
	        String md5Hashcode = Md5Util.getFileStreamMD5((FileInputStream)file.getInputStream(),file.getSize());
	        // 生成目标文件路径
	        //真实的文件名存储到数据库中
	        String fileName = file.getOriginalFilename();
	        //文件后缀名
	        String suffixName = fileName.substring(fileName.lastIndexOf("."));
	        //生成新的文件名，存储时使用，避免重复上传相同名称的文件，相互覆盖
	        String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
	        String dataPath = this.logDatePath();
	        String filePath = dirPath + dataPath + uuid+suffixName;
//	        String filePath = dirPath + File.separator + uuid+suffixName;
	        File destFile = new File(filePath);
	        LOGGER.info("文件存储路径-----------"+filePath);
	        // 检测是否存在目录
	        if (!destFile.getParentFile().exists()) {
	        	destFile.getParentFile().mkdirs();// 新建文件夹
	        }
	        try
	        {
	            // 记录上传记录
	            // 保存文件
	            file.transferTo(destFile);
	            AppFileStoreBean  appFileStoreBean = new AppFileStoreBean();
	            appFileStoreBean.setId(uuid);
	            appFileStoreBean.setIsDeleted(0);
	            appFileStoreBean.setName(fileName);
	            appFileStoreBean.setMimeType(suffixName);
	            appFileStoreBean.setSize(Long.valueOf(file.getSize()).intValue());
	            appFileStoreBean.setFilePath(dataPath);
	            appFileStoreBean.setHashCode(md5Hashcode);
	            Boolean flag = appFileStoreService.saveAppFileStore(appFileStoreBean);
	            if(!flag){
	            	throw new PaasBaseException("000001","文件信息存储失败！");
	            }
	            AppInfoFileBean appInfoFileBean = new AppInfoFileBean();
	    		appInfoFileBean.setId(uuid);
	    		appInfoFileBean.setIsDeleted(0);
	    		appInfoFileBean.setType(2);
	    		appInfoFileBean.setFileName(fileName);
	    		appInfoFileBean.setFileStoreId(uuid);
	    		appInfoFileBean.setRemark(deviceId);
	    		flag = appInfoFileService.saveAppInfoFile(appInfoFileBean);
	            if(!flag){
	            	throw new PaasBaseException("000001","存储文件信息失败！！！");
	            }
	            // 读取文件数据保存到数据库
	            //返回前端数据
	            AppInfoFileResDTO appInfoFileResDTO = new AppInfoFileResDTO();
	            AppInfoFileDTO appInfoFileDTO = new AppInfoFileDTO();
	            appInfoFileDTO.setId(uuid);
	            appInfoFileDTO.setFileName(fileName);
	            appInfoFileResDTO.setAppInfoFileDTO(appInfoFileDTO);
	            return new PaasBaseResponse<>(appInfoFileResDTO);
	        }
	        catch (Exception e)
	        {
	        	e.printStackTrace();
	        	throw new PaasBaseException("000001", "上传文件失败");
	        }
	}

	
	/**
	 * 终端日志文件上传接口
	 * @throws IOException 
	 * */
	@PostMapping("/uploadFile")
	public String uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
		 if (file.isEmpty())
	        {
			 throw new PaasBaseException("000001", "未发现导出文件");
	        }
	        // 创建父文件夹
//	      String dirPath = "F:/upload" ;
	        String dirPath = config.fileStorePath ;
	        String md5Hashcode = Md5Util.getFileStreamMD5((FileInputStream)file.getInputStream(),file.getSize());
	        // 生成目标文件路径
	        //真实的文件名存储到数据库中
	        String fileName = file.getOriginalFilename();
	        //apk版本号
	        String fileVersion = "";
	        //文件后缀名
	        String suffixName = fileName.substring(fileName.lastIndexOf("."));
	        //生成新的文件名，存储时使用，避免重复上传相同名称的文件，相互覆盖
	        String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
	        String dataPath = this.datePath();
	        String filePath = dirPath + dataPath + uuid+suffixName;
//	        String filePath = dirPath + File.separator + uuid+suffixName;
	        File destFile = new File(filePath);
	        // 检测是否存在目录
	        if (!destFile.getParentFile().exists()) {
	        	destFile.getParentFile().mkdirs();// 新建文件夹
	        }
	        try
	        {
	            // 记录上传记录
	            // 保存文件
	            file.transferTo(destFile);
	            return "success";
	        }
	        catch (Exception e)
	        {
	        	e.printStackTrace();
	        	throw new PaasBaseException("000001", "上传文件失败");
	        }
	}

	@GetMapping(value = "/downloadFile")
    public void downloadFile(HttpServletRequest request, HttpServletResponse res) {
	  String id = request.getParameter("id");
	  String name = request.getParameter("name");
	  String path = request.getParameter("path");
      String fileName = name;
      res.setHeader("content-type", "application/octet-stream");
      res.setContentType("application/octet-stream");
      res.setHeader("Content-Disposition", "attachment;filename=\"" + fileName+"\"");
      String dirPath = config.fileStorePath;
      String filePath = dirPath + path + name ;
      byte[] buff = new byte[1024];
      BufferedInputStream bis = null;
      OutputStream os = null;
      try {
        os = res.getOutputStream();
        bis = new BufferedInputStream(new FileInputStream(new File(filePath)));
        int i = bis.read(buff);
        while (i != -1) {
          os.write(buff, 0, i);
          i = bis.read(buff);
        }
        
      } catch (IOException e) {
        e.printStackTrace();
      } finally {
        if (os != null) {
          try {
        	  os.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
        if (bis != null) {
            try {
            	bis.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
      }
    }
	
	private String datePath(){
		String path = "";
		Date date = new Date();  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");  
        path =File.separator + sdf.format(date) + File.separator;
		return path;
	}
	
	private String logDatePath(){
		String path = "";
		Date date = new Date();  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");  
        path =File.separator + sdf.format(date)+"_log" + File.separator;
		return path;
	}
	
}
